#!/usr/bin/env python
import sys
import os
import os.path
import time
import shutil
import subprocess

INSYNC_CONFIG_DIR = '%s/Library/Application Support/Insync' % os.getenv('HOME')
G_HOME = '/Volumes/Google Docs'
G_BOOTSTRAP_DIR = '%s/.Bootstrap' % G_HOME
G_INSYNC_DIR = '%s/.Data/Insync' % G_HOME
G_SYSTEM_DIR = '%s/.System' % G_HOME
G_ACCOUNT_DIR = '%s/.Account' % G_HOME
G_PACKAGE_DIR = '%s/.Package' % G_HOME
G_PACKAGE_UNINSTALL_PY = '%s/bin/uninstall.py' % G_PACKAGE_DIR
G_PACKAGE_INSTALL_PY = '%s/bin/install.py' % G_PACKAGE_DIR

def main():
	install_insync()
	call('killall', 'Insync', ignore_errors=True)
	configure_insync()
	account_dir = block_get_account_dir()
	if not os.path.exists(G_ACCOUNT_DIR):
		os.symlink(account_dir, G_ACCOUNT_DIR)
	if not os.path.exists(G_SYSTEM_DIR):
		os.symlink('%s/J Capital IT' % account_dir, G_SYSTEM_DIR)
	upgrade()
	print('[Info] Finished successfully')

def install_insync():
	if os.path.exists('/Applications/Insync.app'):
		print('[Skip] Insync app already installed')
	else:
		print('[Info] Install Insync')
		call('unzip', '%s/Insync-app.zip' % G_BOOTSTRAP_DIR, '-d', '/Applications')

def configure_insync():
	if os.path.exists(INSYNC_CONFIG_DIR):
		print('[Skip] Insync already configured')
	else:
		print('[Info] Please configure Insync, launching it now...')
		call('unzip', '%s/Insync-config.zip' % G_BOOTSTRAP_DIR, '-d', os.path.dirname(INSYNC_CONFIG_DIR))
		if not os.path.exists(G_INSYNC_DIR):
			os.makedirs(G_INSYNC_DIR)
	call('open', '-a', 'Insync')

def block_get_account_dir():
	account_dir = try_get_account_dir()
	if account_dir:
		return account_dir
	else:
		print('[Wait] Wait for files being synced...')
	while True:
		account_dir = try_get_account_dir()
		if account_dir:
			return account_dir
		else:
			time.sleep(3)

def try_get_account_dir():
	if not os.path.exists(G_INSYNC_DIR):
		return None
	dirs = [dir for dir in os.listdir(G_INSYNC_DIR) if '@' in dir]
	if not dirs:
		return None
	else:
		if len(dirs) > 1:
			print('[Error] More than one account found under directory "%s"' % G_INSYNC_DIR)
			sys.exit(1)
		account_dir = '%s/%s' % (G_INSYNC_DIR, dirs[0])
		if is_system_dir_complete('%s/J Capital IT' % account_dir):
			return account_dir
		else:
			return None

def is_system_dir_complete(system_dir):
	if not os.path.exists('%s/VERSION.txt' % system_dir):
		return False
	if not os.path.exists('%s/Package.zip' % system_dir):
		return False
	return True

def upgrade():
	if should_upgrade():
		print('[Info] Found newer package, upgrade...')
		uninstall_package()
		call('unzip', '%s/Package.zip' % G_SYSTEM_DIR, '-d', G_PACKAGE_DIR)
		shutil.copy2('%s/VERSION.txt' % G_SYSTEM_DIR, '%s/.VERSION.txt' % G_HOME)
		install_package()
	else:
		print('[Skip] Package is up to date')

def should_upgrade():
	if not os.path.exists('%s/.VERSION.txt' % G_HOME):
		return True
	with open('%s/.VERSION.txt' % G_HOME) as f:
		local_version = int(f.read())
	with open('%s/VERSION.txt' % G_SYSTEM_DIR) as f:
		remote_version = int(f.read())
	return remote_version > local_version

def uninstall_package():
	if os.path.exists(G_PACKAGE_UNINSTALL_PY):
		call('python', G_PACKAGE_UNINSTALL_PY)

def install_package():
	call('python', G_PACKAGE_INSTALL_PY)

def call(*cmd, **kwargs):
	ignore_errors = kwargs.get('ignore_errors', False)
	if subprocess.call(cmd) and not ignore_errors:
		print('[Error] Failed to execute "%s"' % ' '.join(cmd))
		sys.exit(1)

main()
